package com.ruoyi.system.netty;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

public class MyStringDecoder extends ByteToMessageDecoder {
    private final int lockMsgLength=17;
    private final int gpsMsgLength=65;
    private boolean gpsFirst =true;
    private boolean lockFirst =true;
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        int length = in.readableBytes();
        Console.error("获取数据长度："+length);
        byte[] bytes = new byte[length];
        try{
            in.markReaderIndex();
            in.readBytes(bytes);//将数据放入 bytes数组
            in.resetReaderIndex();
            String ss = HexUtil.encodeHexStr(bytes);
            Console.error("数据转字符串："+ss);
            String substring=ss.substring(0, 2);
            if("fe".equals(substring)){//锁车消息
                if(lockFirst){
                    if(length==lockMsgLength){//lock
                        Console.log("锁车数据长度复合要求...time="+ DateUtil.now());
                        lockFirst=true;
                        byte[] tmp = new byte[lockMsgLength];
                        in.readBytes(tmp);//读取数据，否则会抛异常
                        out.add(bytes);
                        in=null;
                    }else{
                        Console.log("锁车数据长度不复合要求...length="+length);
                        lockFirst=false;
                        //出现半包或粘包现象
                        ByteBuf res = this.decode(ctx, in,lockMsgLength);
                        if (res != null) {//全包
                            byte[] tmp = new byte[lockMsgLength];
                            res.readBytes(tmp);
                            System.out.println("锁车数据出现粘包...");
                            out.add(tmp);
                            in=null;
                        }else{
                            System.out.println("锁车数据出现半包...");
                            in.readBytes(bytes);//数据丢弃...
                            in=null;
                        }
                    }
                }else{
                    ByteBuf res = this.decode(ctx, in,lockMsgLength);
                    if (res != null) {
                        byte[] tmp = new byte[res.readableBytes()];
                        res.readBytes(tmp);
                        String str = StrUtil.str(tmp,"utf-8");
                        out.add(str);
                        res.release();
                    }
                }
            }else if("4c".equals(substring)){//gps
                if(gpsFirst){
                    if(length==gpsMsgLength){
                        gpsFirst=true;
                        byte[] tmp = new byte[gpsMsgLength];
                        in.readBytes(tmp);//读取数据，否则会抛异常
                        String str = StrUtil.str(bytes,"utf-8");
                        Console.log("gps数据长度复合要求:"+str+",time:"+ DateUtil.now());
                        out.add(str);
                        in=null;
                    }else{
                        Console.log("gps数据长度不复合要求...length="+length);
                        gpsFirst=false;
                        //出现半包或粘包现象
                        ByteBuf res = this.decode(ctx, in,gpsMsgLength);
                        if (res != null) {
                            byte[] tmp = new byte[gpsMsgLength];
                            res.readBytes(tmp);
                            String str = StrUtil.str(tmp,"utf-8");
                            Console.error("gps出现粘包...");
                            out.add(str);
                            in=null;
                        }else{
                            gpsFirst=true;
                            in.readBytes(bytes);//数据丢弃...
                            in=null;
                            System.out.println("gps数据出现半包...");
                        }
                    }
                }else{
                    ByteBuf res = this.decode(ctx, in,gpsMsgLength);
                    if (res != null) {
                        byte[] tmp = new byte[res.readableBytes()];
                        res.readBytes(tmp);
                        String str = StrUtil.str(tmp,"utf-8");
                        out.add(str);
                        res.release();
                    }
                }
            }else{
                System.out.println("\n其他数据：");
                String s1 = HexUtil.encodeHexStr(bytes);
                System.out.println("16进制转字符串："+s1);
                String s2 = StrUtil.str(bytes,"utf-8");
                System.out.println("字符串："+s2);
                in.readBytes(bytes);//数据丢弃...
                in=null;
            }
        }catch (Exception ex){
            in.readBytes(bytes);//数据丢弃...
            in=null;
            Console.error(ex.getMessage());
        }

    }

    private ByteBuf decode(ChannelHandlerContext ctx, ByteBuf in,int length) throws Exception {
        return in.readableBytes() < length ? null : in.readRetainedSlice(length);
    }

//    public static void main(String[] args) {
//        String s="LNG = 117.15618134, LAT = 34.15148926, TIME = 2022-02-22 11:02:58";
//        String s2="febb0101010101010101010101010d0a";
//        String s1 = HexUtil.encodeHexStr(s2.getBytes());
//        System.out.println(s1);
//        //4c4e47203d203131372e31353631383133342c204c4154203d2033342e31353134383932362c2054494d45203d20323032322d30322d32322031313a30323a3538
//
//    }
//
//    public static void main(String[] args) {
//        byte[] s = {1,2,3,4,5,6,7,8};
//        byte [] y = new byte[7];
//        for (int k = 0; k < y.length; k++) {
//            y[k]=s[k];
//        }
//        String s1 = HexUtil.encodeHexStr(y);
//        System.out.println(s1);
//    }

}
